package com.citcc.api.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import com.citcc.api.utils.RedisUtil;

import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

@Configuration
public class RedisConfig {

	 	@Value("${spring.redis.host}")
	    private String host;
	 
	    @Value("${spring.redis.port}")
	    private int port;
	 
	    @Value("${spring.redis.timeout}")
	    private int timeout;
	 
	    @Value("${spring.redis.jedis.pool.max-idle}")
	    private int maxIdle;
	 
	    @Value("${spring.redis.jedis.pool.max-wait}")
	    private long maxWaitMillis;
	 
	    @Value("${spring.redis.password}")
	    private String password;
	   
	    @Value("${spring.redis.maxTotal}")
	    private int maxTotal;
	    
	    @Value("${spring.redis.testWhileIdle}")
	    private boolean testWhileIdle;
	   
	    @Value("${spring.redis.testOnBorrow}")
	    private boolean testOnBorrow;
	 
	    @Value("${spring.redis.database}")
	    private int database;
	    
	    @Bean
	    public JedisPool redisPoolFactory()  throws Exception{
	        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
	        jedisPoolConfig.setMaxIdle(maxIdle);
	        jedisPoolConfig.setMaxWaitMillis(maxWaitMillis);
	        jedisPoolConfig.setMaxTotal(maxTotal);
	        // 是否启用pool的jmx管理功能, 默认true
	        jedisPoolConfig.setJmxEnabled(true);
	        // 是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个
	        jedisPoolConfig.setTestOnBorrow(testOnBorrow);
	        // 在空闲时检查有效性, 默认false
	        jedisPoolConfig.setTestWhileIdle(testWhileIdle);
	        JedisPool jedisPool = new JedisPool(jedisPoolConfig, host, port, timeout, password, database);
	        return jedisPool;
	    }

	    /**
	     * 实例化 RedisTemplate 对象
	     *
	     * @return
	     */
	    @Bean
	    public RedisTemplate<String, Object> functionDomainRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
	        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
	        initDomainRedisTemplate(redisTemplate, redisConnectionFactory);
	        return redisTemplate;
	    }
	    /**
	     * 设置数据存入 redis 的序列化方式,并开启事务
	     * 
	     * @param redisTemplate
	     * @param factory
	     */
	    private void initDomainRedisTemplate(RedisTemplate<String, Object> redisTemplate, RedisConnectionFactory factory) {
	        //如果不配置Serializer，那么存储的时候缺省使用String，如果用User类型存储，那么会提示错误User can't cast to String！  
	        redisTemplate.setKeySerializer(new StringRedisSerializer());
	        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
	        redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
	        redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
	        // 开启事务
	        redisTemplate.setEnableTransactionSupport(true);
	        redisTemplate.setConnectionFactory(factory);
	    }
	    /**
	     * 注入封装RedisTemplate
	    * @Title: redisUtil 
	    * @return RedisUtil
	    * @throws
	     */
	    @Bean(name = "redisUtil")
	    public RedisUtil redisUtil(RedisTemplate<String, Object> redisTemplate) {
	        RedisUtil redisUtil = new RedisUtil();
	        redisUtil.setRedisTemplate(redisTemplate);
	        return redisUtil;
	    }
}
